﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Controls.Maps;
using System.Globalization;
using System.Collections.ObjectModel;
using PhoneApp1.GeocoderService;
using Microsoft.Phone.Shell;
using System.IO.IsolatedStorage;

namespace TaxiTouchClient
{
    public partial class Client_geo_auto : PhoneApplicationPage
    {
        private const string mapKey = @"Ai8yroXkpmcBvxqn1TXtjlQhy3FJcObwJpvgxzOEDfgcvaJlOP2CCdCh585njAjA";
        private GeoCoordinateWatcher geoWatcher;
        private Pushpin pushpin;
        public delegate void GetAddressAsynchHandler(Address address);
        public event GetAddressAsynchHandler GetAddressAsyncCompleted;
        private string adresse;
        private GeocodeResult localite;
        private Microsoft.Phone.Controls.Maps.LocationCollection collec;
        GeoCoordinate coord;

        public Client_geo_auto()
        {
            InitializeComponent();
            if (IsolatedStorageSettings.ApplicationSettings.Contains("LocalisationClient"))
            {
                localite = (GeocodeResult)IsolatedStorageSettings.ApplicationSettings["LocalisationClient"];
                adresse = localite.DisplayName;
            }
            geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            geoWatcher.StatusChanged += geoWatcher_StatusChanged;
            //geoWatcher.PositionChanged += geoWatcher_PositionChanged;
            geoWatcher.Start();
        }

        private void geoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {

                case GeoPositionStatus.Disabled:
                    // le gps n'est pas activé
                    break;
                case GeoPositionStatus.Initializing:
                    // le gps est en cours d'initialisation
                    break;
                case GeoPositionStatus.NoData:
                    // il n'y a pas d'informations
                    break;
                case GeoPositionStatus.Ready:
                    // le GPS est activé et disponible                    
                    break;
            }
        }

        private void map_Loaded(object sender, RoutedEventArgs e)
        {

            Dispatcher.BeginInvoke(() =>
            {
                if (adresse != null && localite != null)
                {
                    coord = new GeoCoordinate(localite.Locations[0].Latitude, localite.Locations[0].Longitude);
                    map.Center = coord;
                    AdresseCli.Text += " " + adresse;
                }
                else
                {
                    coord = new GeoCoordinate(geoWatcher.Position.Location.Latitude, geoWatcher.Position.Location.Longitude);
                    map.Center = coord;
                    getAdress(geoWatcher.Position);
                }
                pushpin = new Pushpin { Location = coord, Style = Resources["PushpinControlTemplateBlue"] as Style, Tag = "MaLoc" };
                map.Children.Add(pushpin);

                map.ZoomLevel = 15;
                map.Mode = new RoadMode();
                /*if (map.Children.OfType<Pushpin>().Any())
                {
                    Pushpin push = (Pushpin)map.Children.First(p => (p.GetType() == typeof(Pushpin) && ((Pushpin)p).Tag.ToString() == "MaLoc"));
                    map.Children.Remove(push);
                    GeoCoordinate loc = new GeoCoordinate{
                        Longitude = localite.Locations[0].Longitude,
                        Latitude = localite.Locations[0].Latitude
                    
                    };
                    pushpin = new Pushpin { Location = loc, Style = Resources["PushpinControlTemplateBlue"] as Style, Tag = "MaLoc" };
                    map.Children.Add(pushpin);
                }
                else
                {
                    pushpin = new Pushpin { Location = geoWatcher.Position.Location, Style = Resources["PushpinControlTemplateBlue"] as Style, Tag = "MaLoc" };
                    map.Children.Add(pushpin);
                }*/

            });


        }
        private void getAdress(GeoPosition<GeoCoordinate> coordinate)
        {
            try
            {
                GeocodeServiceClient geocodeserviceclient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");

                var request = new ReverseGeocodeRequest();
                request.Credentials = new PhoneApp1.GeocoderService.Credentials { ApplicationId = mapKey };

                request.Location = new Location()
                {
                    Latitude = coordinate.Location.Latitude,
                    Longitude = coordinate.Location.Longitude
                };

                request.ExecutionOptions = new ExecutionOptions { SuppressFaults = true };

                geocodeserviceclient.ReverseGeocodeCompleted += GeoCodeCompletedloc;
                geocodeserviceclient.ReverseGeocodeAsync(request);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void GeoCodeCompletedloc(object sender, ReverseGeocodeCompletedEventArgs e)
        {
            //Everytime, there's only one result...
            if (e.Result != null && e.Result.Results.Count > 0)
            {
                //GetAddressAsyncCompleted(e.Result.Results[0].Address);
                adresse = e.Result.Results[0].DisplayName.ToString();
                AdresseCli.Text += " " + adresse;
                localite = e.Result.Results[0];
                IsolatedStorageSettings.ApplicationSettings.Add("LocalisationClient", localite);
                IsolatedStorageSettings.ApplicationSettings.Add("AdresseClient", adresse);
            }
            else
            {
                AdresseCli.Text += "Language géolocalisation a échouée, veuillez entrer l'adresse manuellement via le bouton \"modifier ci-dessous";
            }

        }

        private void CalculRoute(Location loc1, Location loc2)
        {
            try
            {
                PhoneApp1.RouteCodeService.RouteRequest routeRequest = new PhoneApp1.RouteCodeService.RouteRequest();

                // Set the credentials using a valid Bing Maps key
                routeRequest.Credentials = new PhoneApp1.RouteCodeService.Credentials();
                routeRequest.Credentials.ApplicationId = mapKey;

                // Set the start, stop, and end points
                PhoneApp1.RouteCodeService.Waypoint[] waypoints = new PhoneApp1.RouteCodeService.Waypoint[2];
                routeRequest.Options = new PhoneApp1.RouteCodeService.RouteOptions();
                routeRequest.Options.RoutePathType = PhoneApp1.RouteCodeService.RoutePathType.Points;
                routeRequest.UserProfile = new PhoneApp1.RouteCodeService.UserProfile();
                routeRequest.UserProfile.DistanceUnit = PhoneApp1.RouteCodeService.DistanceUnit.Kilometer;
                waypoints[0] = new PhoneApp1.RouteCodeService.Waypoint();
                waypoints[0].Description = "Start";
                waypoints[0].Location = new PhoneApp1.RouteCodeService.Location();
                waypoints[0].Location.Latitude = loc1.Latitude;
                waypoints[0].Location.Longitude = loc1.Longitude;
                waypoints[1] = new PhoneApp1.RouteCodeService.Waypoint();
                waypoints[1].Description = "End";
                waypoints[1].Location = new PhoneApp1.RouteCodeService.Location();
                waypoints[1].Location.Latitude = loc2.Latitude;
                waypoints[1].Location.Longitude = loc2.Longitude;

                routeRequest.Waypoints = waypoints;

                // Make the calculate route request
                PhoneApp1.RouteCodeService.RouteServiceClient routeService = new PhoneApp1.RouteCodeService.RouteServiceClient("BasicHttpBinding_IRouteService");
                routeService.CalculateRouteCompleted += RouteComplete;

                routeService.CalculateRouteAsync(routeRequest);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

            }

        }

        private void RouteComplete(object sender, PhoneApp1.RouteCodeService.CalculateRouteCompletedEventArgs e)
        {
            PhoneApp1.RouteCodeService.RouteResult resultat = e.Result.Result;
            MessageBox.Show("distance " + resultat.Summary.Distance + " temps moyen : " + resultat.Summary.TimeInSeconds);

            Color routeColor = Colors.Blue;
            SolidColorBrush routeBrush = new SolidColorBrush(routeColor);
            MapPolyline routeLine = new MapPolyline();
            routeLine.Locations = new LocationCollection();
            routeLine.Stroke = routeBrush;
            routeLine.Opacity = 0.65;
            routeLine.StrokeThickness = 5.0;

            double north, west, south, east;
            north = south = e.Result.Result.RoutePath.Points[0].Latitude;
            west = east = e.Result.Result.RoutePath.Points[0].Longitude;

            //MapLayer myRouteLayer = new MapLayer();
            //map1.Children.Add(myRouteLayer);

            foreach (PhoneApp1.RouteCodeService.Location p in e.Result.Result.RoutePath.Points)
            {
                Ellipse pointer = new Ellipse();
                pointer.Width = 5;
                pointer.Height = 5;
                pointer.Fill = new SolidColorBrush(Colors.Red);
                pointer.Opacity = 0.65;
                GeoCoordinate test = new GeoCoordinate();
                test.Latitude = p.Latitude;
                test.Longitude = p.Longitude;
                Pushpin psh = new Pushpin { Location = test, Style = Resources["PushpinControlTemplateTraj"] as Style };
                map.Children.Add(psh);


                /*
                
                if (north < p.Latitude) north = p.Latitude;
                if (west > p.Longitude) west = p.Longitude;
                if (south > p.Latitude) south = p.Latitude;
                if (east < p.Longitude) east = p.Longitude;

                routeLine.Locations.Add(test);*/

                Location location = new Location();
                location.Longitude = p.Longitude;
                location.Latitude = p.Latitude;

                //MapLayer.SetPosition(pointer, location);
                //MapLayer.SetPositionOrigin(pointer, PositionOrigin.Center);

                // Add the drawn point to the route layer.                    
                //map1.Children.Add(routeLine);
            }
            // Add a map layer in which to draw the route.


            // Add the route line to the new layer.
            //myRouteLayer.Children.Add(routeLine);

            //LocationRect rect = new LocationRect(north, west, south, east);
        }

        private void Valider_ClientGeoAuto_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/Client_accueil.xaml", UriKind.Relative));
        }

        private void Modifier_ClientGeoAuto_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/Client_geo_manu.xaml", UriKind.Relative));
        }
    }
}